import math
import pyautogui
import time
import random
import os
import datetime
import json
import json
import os
import sys
import threading
import queue
import pyperclip
import win32gui
import win32process
import psutil
import subprocess
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, 
                            QTextEdit, QVBoxLayout, QWidget)
from PyQt5.QtCore import Qt, QTimer, QObject, pyqtSignal
from app.interface_walmart.MySQLHelper_walmart import MySQLHelper
import uuid
import random
from datetime import datetime
import traceback
import pytesseract
import requests
from  follow_baidu import baidu_ocr
from io import BytesIO
import base64
from follow_baidu1 import baidu_baidu1
class WorkSignals(QObject):
    message = pyqtSignal(str)

class WorkThread(threading.Thread):
    def __init__(self, json_path, signal):
        super().__init__()
        self.json_path = json_path
        self.signals = signal
        self._stop_event = threading.Event()

    def run(self):
        """线程执行函数"""
        try:
            
            a=1
            
        except Exception as e:
            self.signals.message.emit(f"错误: {str(e)}\n")

    def stop(self):
        self._stop_event.set()

    def stopped(self):
        return self._stop_event.is_set()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.work_thread = None
        self.signals = WorkSignals()
        self.signals.message.connect(self.update_memo)
        self.start_btn.click()

    def init_ui(self):
        self.setWindowTitle('RPA跟卖')
        self.setGeometry(100, 100, 800, 600)
        self.start_btn = QPushButton('开始跟卖任务', self)
        self.start_btn.clicked.connect(self.start_task)
        self.text_memo = QTextEdit(self)
        self.text_memo.setReadOnly(True)
        layout = QVBoxLayout()
        layout.addWidget(self.start_btn)
        layout.addWidget(self.text_memo)
        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)
        path1= self.get_latest_process_path()
        print(path1)

        self.dbhelper=MySQLHelper()
        sql='select * from app_zbirdaccount '
        ziniaoaccount=self.dbhelper.query(sql)
        # print(ziniaoaccount)
        for row in ziniaoaccount:
            print(row['loginname'])
            print(row['password'])
            self.ziniao_login(row['id'],row['loginname'],row['password'])
    def check_country_origin_in_active_window2(self,text_tofind):
        try:
            # 获取当前活动窗口位置
            hwnd = win32gui.GetForegroundWindow()
            rect = win32gui.GetWindowRect(hwnd)
            left, top, right, bottom = rect
            window_width = right - left
            window_height = bottom - top

            # 截取窗口区域
            screenshot = pyautogui.screenshot(region=(left, top, window_width, window_height))
            
            # 转换为base64
            buffered = BytesIO()
            screenshot.save(buffered, format="PNG")
            img_base64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
            response=baidu_baidu1(img_base64)
            # 调用百度OCR高精度接口（需开通服务）
            
            result = response.json()

            # 解析坐标
            target_coordinates = []
            if 'words_result' in result:
                for item in result['words_result']:
                    if text_tofind in item['words']:
                        return True # 获取文字区域顶点坐标（相对于截图）
            return False            

        except Exception as e:
            print(f"坐标获取失败: {str(e)}")
            return []
    def check_country_origin_in_active_window(self):
        """检查最前窗口是否包含Country of Origin文字"""
        try:
            # 获取最前窗口的位置信息
            hwnd = win32gui.GetForegroundWindow()
            rect = win32gui.GetWindowRect(hwnd)
            # 截取窗口区域
            left, top, right, bottom = rect
            width = right - left
            height = bottom - top
            screenshot = pyautogui.screenshot(region=(left, top, width, height))
            # OCR识别
            baidu_ocr(screenshot)
             
        except Exception as e:
            print(f"窗口文字检测失败: {str(e)}")
            traceback.print_exc()
            return False        
    import math
import time

def human_like_move_and_click(self,dest_x, dest_y, duration=0.8, click=True):
    """模拟人类鼠标移动
    :param dest_x: 目标X坐标
    :param dest_y: 目标Y坐标
    :param duration: 移动总时间（秒）
    :param click: 是否最后执行点击
    """
    try:
        # 获取初始位置
        start_x, start_y = pyautogui.position()
        
        # 计算移动路径参数
        distance = math.hypot(dest_x - start_x, dest_y - start_y)
        steps = max(int(distance / 2), 10)  # 至少10步
        step_time = duration / steps
        
        # 生成带扰动的移动路径
        for i in range(steps):
            # 使用缓动函数（easeOutQuad）
            t = (i + 1) / steps
            progress = 1 - (1 - t) ** 2
            current_x = start_x + (dest_x - start_x) * progress
            current_y = start_y + (dest_y - start_y) * progress
            
            # 添加随机扰动（不超过5像素）
            current_x += random.uniform(-3, 3)
            current_y += random.uniform(-3, 3)
            
            # 确保坐标在屏幕范围内
            current_x = max(0, min(pyautogui.size().width, current_x))
            current_y = max(0, min(pyautogui.size().height, current_y))
            
            pyautogui.moveTo(current_x, current_y, duration=step_time)
            
            # 添加随机延迟（最后几步更慢）
            if i > steps - 3:
                time.sleep(random.uniform(0.02, 0.05))
        
        # 最终精确移动
        pyautogui.moveTo(dest_x, dest_y, duration=0.1)
        
        if click:
            # 模拟人类点击（按下和释放分开）
            pyautogui.mouseDown()
            time.sleep(random.uniform(0.05, 0.15))
            pyautogui.mouseUp()
            
    except pyautogui.FailSafeException:
        raise
    except Exception as e:
        print(f"鼠标移动失败: {str(e)}")
    def ziniao_login(self,zbird_account_id,ziniaoaccount,ziniaopassword):
      
        # self.check_country_origin_in_active_window()
        self.text_memo.append("开始执行任务...\n")
        self.text_memo.append("正在启动紫鸟客户端...\n")
        pyautogui.FAILSAFE = True
        pyautogui.PAUSE = 1
        orderindex=0
        addtionalheight=(orderindex -1)*88
        # 进行登录操作
        sql=f'select * from app_walmartaccount  where zbird_account_id={zbird_account_id}'
        walmartaccount=self.dbhelper.query(sql)
        if len(walmartaccount)==0:
            return
        
        subprocess.Popen(r"F:\Program Files\ziniao\ziniao.exe")
        path1=self.get_latest_process_path()
        # while path1 != r"F:\Program Files\ziniao\ziniao.exe":
        #     time.sleep(0.3)
        #     path1=self.get_latest_process_path()

        pyautogui.click(1601,29)
        # 第二部,退出当前用户登录
        path1=self.get_latest_process_path()
        print(1,path1)

        pyautogui.click(1518,370)
        path1=self.get_latest_process_path()

        # 第三步
        time.sleep(0.5)

        pyautogui.click(1800, 472)
        pyautogui.press('backspace', presses=20)
        time.sleep(0.5)
        pyperclip.copy(ziniaoaccount)
        pyautogui.hotkey('ctrl', 'v') 
        # 第四步
        pyautogui.click(1554, 540)
        pyautogui.press('backspace', presses=20)
        time.sleep(0.5)
        pyautogui.write( ziniaopassword,interval=0.1)
        # 第五步登录
        pyautogui.click(1700, 660)
        time.sleep(5.5)
        path1=self.get_latest_process_path()
        print(5,path1)

        for row2 in walmartaccount:
            sql2=f'select * from app_skus_new  where is_following=1 and walmart_account_id={row2["id"]}'
            data_app_skus=self.dbhelper.query(sql2)
            if len(data_app_skus)>0:
                orderindex=row2['orderindex']
                addtionalheight=(orderindex -1)*88
                # 第六步，等待出现新页面，在这里，选择账号，需要按照每个沃尔玛账号的顺序，进行点击
                pyautogui.click(1832, 231 + addtionalheight)
                path1=self.get_latest_process_path()

                print(6,path1)

                # 第七步，等待出现新页面
                time.sleep(5.5)
                path1=self.get_latest_process_path()
                print(7,path1)

                pyautogui.click(889, 466)

                # 第八步等待出现新页面
                time.sleep(5.5)
                path1=self.get_latest_process_path()
                print(8,path1)
                pyautogui.click(1155, 527)
                time.sleep(6.5)
                # 最后一步登录
                pyautogui.click(1138, 533)
                time.sleep(1.5) 
                path1=self.get_latest_process_path()
                print(9,path1)
                path1=self.get_latest_process_path()
                print(10,path1)
                
                self.ziniao_follow(row2 ,data_app_skus)


        # pyautogui.click(76, 293)

        # pyautogui.click(1820, 274)
        
                # 开始循环 跟卖这个吧00766236069722
    def ziniao_follow(self,row_walmart_account,data_app_skus):  
        hoursdiff=12
        username=row_walmart_account['username']
        now = datetime.now()
        code_part =random.choice("ABCDEF")                  # 固定代号
        year_part = str(now.year)[-1]      # 年份最后一位
        month_part = f"{now.month:02d}"    # 两位数月份
        prefix_part =random.choice("GHIJKLM")                # 固定前缀

        for index,row in enumerate(data_app_skus,start=1) :
            print(row['sku'])
            # pyautogui.scroll(200)
            full_uuid = str(uuid.uuid4())
            first_segment = full_uuid.split('-')[0]
            leng1=random.randint(5,len(first_segment)-1)
            serial_part =first_segment[:leng1] # 4位序
            sku=row['sku']
            price=row['price']
            new_sku_code=f"{code_part}{year_part}{month_part}{prefix_part}{serial_part}"
            print(new_sku_code)
            sql=f'select * from sku_keywords_history where sku="{sku}" and abs(toprice-{price})>0.01'
            data_sku_keywords_history=self.dbhelper.query(sql)
            print(sql)

            if len(data_sku_keywords_history)>0:
                continue
            
            try:
                if index==1:
                    pyautogui.click(747, 836)
                    pyautogui.press('backspace', presses=20)  # 按20次退格键
                    pyautogui.write(row['upc'], interval=0.1)
                    pyautogui.press('enter',presses=1)  
                    # pyautogui.click(700, 938) 
                    
                    # 点击下一步: 
                    pyautogui.scroll(-200)
                    pyautogui.click(685, 912)
                else:
                    pyautogui.click(655, 532)
                    pyautogui.press('backspace', presses=20)  # 按20次退格键
                    pyautogui.write(row['sku'], interval=0.1)
                    pyautogui.press('enter', presses=1)  
                    pyautogui.click(709, 777)
                # 开始进入新页面
                time.sleep(0.5)
                pyautogui.click(587, 404)
                time.sleep(0.1)
                pyautogui.write('sk23u1', interval=0.1)

                time.sleep(0.5)
                pyautogui.click(956, 398)
                pyautogui.write(row['price']+2, interval=0.1)
                time.sleep(0.5)
                pyautogui.write('1',interval=0.1)
                # 开始选择重量单位
                pyautogui.click(1081, 640)
                pyautogui.click(1055, 686)
                #可能要搞个判断，如果出现Country of Origin，则不进行下一步
                if self.check_country_origin_in_active_window2("Country of Origin"):
                    for ix in range(32):
                        time.sleep(0.02 *random.random())
                        pyautogui.scroll(-100)  # 向下滚动
                    
                    pyautogui.click(60, 1174)
                    # 上面是选择发货地
                    pyautogui.click(487, 825)
                    # 上面是点击税号，
                # 写税号
                pyautogui.click(487, 825)
                # 写税号
                pyautogui.write('234232331', interval=0.1)
                # 点击提交
                pyautogui.click(1852, 1026)
                # 关闭当前窗口，继续下一次循环
                time.sleep(5.5)
                pyautogui.click(734, 18) 
                sql=f'insert into sku_keywords_history (sku,opdate,fromprice,toprice,username) values ("{sku}",now(),0,{price},"{username}")'
                print(sql)
                self.dbhelper.execute(sql)
                sql=f'update app_skus_new set newsku="{new_sku_code}",newprice={price} where id={row["id"]}'
                self.dbhelper.execute(sql)
            except Exception as e:
                print(f'跟卖失败{sku}->{new_sku_code}->{price}')
                traceback.print_exc()    
    def get_latest_process_path(self):
        """获取最新打开的窗口程序路径"""
        try:
            latest_time = 0
            latest_path = None
            # 遍历所有进程找最新创建的
            for proc in psutil.process_iter(['pid', 'name', 'create_time', 'exe']):
                try:
                    if proc.info['create_time'] > latest_time:
                        latest_time = proc.info['create_time']
                        latest_path = proc.info['exe']
                except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                    continue
                    
            return latest_path
        except Exception as e:
            print(f"获取最新进程路径失败: {str(e)}")
            return None
    def get_latest_process_path(self):
        """获取当前最前窗口的程序路径"""
        try:
            # 获取前台窗口句柄
            hwnd = win32gui.GetForegroundWindow()
            # 获取进程ID
            _, pid = win32process.GetWindowThreadProcessId(hwnd)
            # 通过进程ID获取进程信息
            process = psutil.Process(pid)
            return process.exe()
        except Exception as e:
            print(f"获取窗口路径失败: {str(e)}")
            return None
     
    def start_task(self):
        """启动任务线程"""
        if self.work_thread and self.work_thread.is_alive():
            return

        current_dir = os.getcwd()
        json_file_path = os.path.join(current_dir, 'app', 'interface', 'rpa_login.json')
        
        self.work_thread = WorkThread(json_file_path, self.signals)
        self.work_thread.start()
        self.start_btn.setEnabled(False)

    def update_memo(self, message):
        """线程安全更新日志"""
        self.text_memo.append(message)

    def closeEvent(self, event):
        """窗口关闭时停止线程"""
        if self.work_thread and self.work_thread.is_alive():
            self.work_thread.stop()
            self.work_thread.join()
        event.accept()

def main():
    # 设置安全选项
    a=2
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

